package cn.com.surker.util;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.stream.Stream;


/**
 * 用于临时转换图片的工具类
 */
public class ImageResizer {

	private static final Set<String> IMAGE_EXTENSIONS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("jpg", "jpeg", "png", "gif", "bmp")));
	private static final long MAX_SIZE_BYTES = 3 * 1024 * 1024; // 3MB
	private static final int MAX_ATTEMPTS = 10; // 最大调整次数

	public static void main(String[] args) throws IOException {
		Path sourceDir = Paths.get("E:\\驰旭\\无人过磅图片识别模板\\大业0604");
		Path targetDir = Paths.get("E:\\驰旭\\无人过磅图片识别模板\\大业0604_new");

		// 确保目标目录存在
		if (!Files.exists(targetDir)) {
			Files.createDirectories(targetDir);
		}

		// 使用Java 8 Stream处理所有图片文件
		try (Stream<Path> stream = Files.walk(sourceDir)) {
			stream
				.filter(Files::isRegularFile)
				.filter(ImageResizer::isImageFile)
				.forEach(source -> processImage(source, targetDir.resolve(sourceDir.relativize(source))));
		}
	}

	// 检查是否为图片文件
	private static boolean isImageFile(Path path) {
		String fileName = path.getFileName().toString().toLowerCase();
		int dotIndex = fileName.lastIndexOf('.');
		if (dotIndex > 0) {
			String ext = fileName.substring(dotIndex + 1);
			return IMAGE_EXTENSIONS.contains(ext);
		}
		return false;
	}

	// 处理单个图片文件
	private static void processImage(Path source, Path target) {
		try {
			// 如果原始文件已小于3MB，直接复制
			if (Files.size(source) <= MAX_SIZE_BYTES) {
				Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
				return;
			}

			// 读取原始图片
			BufferedImage originalImage = ImageIO.read(source.toFile());
			if (originalImage == null) return;

			// 获取文件格式
			String formatName = getFormatName(source);

			// 逐步缩小图片
			BufferedImage resizedImage = originalImage;
			int attempts = 0;
			long currentSize = Files.size(source);

			while (currentSize > MAX_SIZE_BYTES && attempts < MAX_ATTEMPTS) {
				// 计算缩放比例（每次缩小15%）
				double scaleFactor = Math.sqrt(0.85); // 面积缩小15%
				int newWidth = (int) (resizedImage.getWidth() * scaleFactor);
				int newHeight = (int) (resizedImage.getHeight() * scaleFactor);

				// 创建缩放后的图片
				resizedImage = resizeImage(resizedImage, newWidth, newHeight);

				// 测试文件大小
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				if (saveImage(resizedImage, formatName, baos)) {
					currentSize = baos.size();
				} else {
					break;
				}

				attempts++;
			}

			// 保存最终结果
			if (saveImage(resizedImage, formatName, target)) {
				System.out.println("处理成功: " + source + " -> " + target + " (" +
					(Files.size(target) / 1024) + "KB)");
			}

		} catch (IOException e) {
			System.err.println("处理失败: " + source + " - " + e.getMessage());
		}
	}

	// 等比例缩放图片
	private static BufferedImage resizeImage(BufferedImage original, int targetWidth, int targetHeight) {
		BufferedImage resized = new BufferedImage(targetWidth, targetHeight, original.getType());
		Graphics2D g = resized.createGraphics();
		g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
		g.drawImage(original, 0, 0, targetWidth, targetHeight, null);
		g.dispose();
		return resized;
	}

	// 获取图片格式
	private static String getFormatName(Path path) {
		String fileName = path.getFileName().toString().toLowerCase();
		if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) return "jpg";
		if (fileName.endsWith(".png")) return "png";
		if (fileName.endsWith(".gif")) return "gif";
		if (fileName.endsWith(".bmp")) return "bmp";
		return "jpg"; // 默认格式
	}

	// 保存图片到文件
	private static boolean saveImage(BufferedImage image, String format, Path target) {
		try (OutputStream os = Files.newOutputStream(target)) {
			return saveImage(image, format, os);
		} catch (IOException e) {
			return false;
		}
	}

	// 保存图片到输出流
	private static boolean saveImage(BufferedImage image, String format, OutputStream os) {
		try {
			// JPEG使用有损压缩
			if ("jpg".equalsIgnoreCase(format) || "jpeg".equalsIgnoreCase(format)) {
				Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpeg");
				if (writers.hasNext()) {
					ImageWriter writer = writers.next();
					try (ImageOutputStream ios = ImageIO.createImageOutputStream(os)) {
						writer.setOutput(ios);
						JPEGImageWriteParam jpegParams = (JPEGImageWriteParam) writer.getDefaultWriteParam();
						jpegParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
						jpegParams.setCompressionQuality(0.85f); // 85%质量
						writer.write(null, new IIOImage(image, null, null), jpegParams);
					}
					writer.dispose();
					return true;
				}
			}
			// 其他格式直接保存
			return ImageIO.write(image, format, os);
		} catch (IOException e) {
			return false;
		}
	}
}
